package commands

import (
	"database/sql"
	"fmt"
	"github.com/sirupsen/logrus"
	"strconv"
	"time"
	"wecom_rebot/common"
	"wecom_rebot/core"
	"wecom_rebot/models"
)

var txSyncLogger *logrus.Logger

// InitTxSyncLogger 移除 init() 函数，改为显式初始化函数
func InitTxSyncLogger() {
	// 确保在 common 初始化后调用
	txSyncLogger = core.InitLogger(common.LogsErrorMap[21])
}

func CopyInsertTencent() {
	// 获取 handle_status = 1 AND type = 1 的所有 parent 值
	var parent []string
	err := common.DB.Model(&models.CopyAccountList{}).
		Where("handle_status = 1 AND type = 1 AND account_id <> 0").
		Group("parent").Pluck("parent", &parent).Error
	if err != nil {
		txSyncLogger.Error("查询 parent 数据出错: ", err)
		fmt.Println("查询 parent 数据出错: ", err)
		return
	}

	if len(parent) == 0 {
		txSyncLogger.Info("没有需要处理的数据")
		fmt.Println("没有需要处理的数据")
		return
	}

	// 查询所有 copy 数据
	var copyS []models.CopyAccountList
	err = common.DB.
		Where("handle_status = 1 AND type = 1 AND account_id <> 0").Find(&copyS).Error
	if err != nil {
		txSyncLogger.Error("查询 copy 数据失败: ", err)
		fmt.Println("查询 copy 数据失败: ", err)
		return
	}

	// 更新 handle_status 为 2
	err = common.DB.Model(&models.CopyAccountList{}).
		Where("handle_status = 1 AND type = 1 AND account_id <> 0").Update("handle_status", 2).Error
	if err != nil {
		txSyncLogger.Error("更新数据出错: ", err)
		fmt.Println("更新数据出错: ", err)
		return
	}

	// 查询 parent 对应的账户信息
	var tencentData []models.TencentAccountView
	err = common.DBDk.Where("account_id IN (?)", parent).Find(&tencentData).Error
	if err != nil {
		txSyncLogger.Error("查询视图数据出错: ", err)
		fmt.Println("查询视图数据出错: ", err)
		return
	}

	// 将 tencentData 转换为 map，以 account_id 为键
	parentMap := make(map[string]models.TencentAccountView)
	for _, item := range tencentData {
		parentMap[item.AccountID] = item
	}

	// 遍历 copyS 处理每条记录
	for _, item := range copyS {

		parent := strconv.Itoa(item.Parent)

		// 检查 parent 是否存在
		parentInfo, exists := parentMap[parent]
		if !exists {
			msg := fmt.Sprintf("%s 不存在广告主表，跳过", parent)
			txSyncLogger.Info(msg)
			fmt.Println(msg)
			continue
		}

		// 构造表名
		tableName := "tencent_" + parentInfo.Suffix

		// 构造插入数据
		insertData := map[string]interface{}{
			"account_id":         item.AccountID,
			"is_robot":           2,
			"open_medium_name":   getValueOrDefault(item.Username, "小助手"),
			"update_medium_name": getValueOrDefault(item.Username, "小助手"),
			"remark":             "小助手复制户" + getValueOrDefault(item.Username, ""),
			"created_at":         time.Now().Format("2006-01-02 15:04:05"),
			"open_time":          time.Now().Format("2006-01-02"),
			"wechat_id":          item.AccountID,
			"medium":             getValueOrDefault(item.Username, "小助手"),
		}

		// 添加 parentInfo 中的其他字段（除了 id）
		TxStructToMap(parentInfo, insertData)

		// 获取表字段列表 - 使用 SHOW COLUMNS FROM 语句
		columns, err := getTableColumns(tableName)
		if err != nil {
			txSyncLogger.Error(fmt.Sprintf("获取表 %s 字段失败: %v", tableName, err))
			fmt.Printf("获取表 %s 字段失败: %v\n", tableName, err)
			continue
		}

		// 过滤数据，只保留允许的字段
		filteredData := filterDataByColumns(insertData, columns)

		// 记录日志
		txSyncLogger.Info(fmt.Sprintf("记录数据: columns=%v, data=%v, copy=%+v", columns, filteredData, item))

		// 插入数据
		err = insertIntoTable(tableName, filteredData)
		if err != nil {
			msg := fmt.Sprintf("%s 新增插入失败，跳过", parent)
			txSyncLogger.Info(msg)
			fmt.Println(msg)
			continue
		}

		// 特殊处理 K4 表
		if isK4Type(parentInfo.Suffix) {
			k4Columns, err := getTableColumns("tencent_K4")
			if err != nil {
				txSyncLogger.Error(fmt.Sprintf("获取表 tencent_K4 字段失败: %v", err))
				fmt.Printf("获取表 tencent_K4 字段失败: %v\n", err)
				continue
			}

			k4FilteredData := filterDataByColumns(insertData, k4Columns)
			err = insertIntoTable("tencent_K4", k4FilteredData)
			if err != nil {
				txSyncLogger.Error(fmt.Sprintf("插入 tencent_K4 表失败: %v", err))
				fmt.Printf("插入 tencent_K4 表失败: %v\n", err)
			}
			// 如果是K4的数据，则根据 province 在根据地区插入到子表 tencent_k4_beijing = 北京 tencent_k4_fujian = 福建 tencent_k4_hainan = 海南 等等
			// 根据 province 插入到对应的子表
			if province, ok := insertData["province"].(string); ok && province != "" {
				// 省份到表名后缀的映射
				provinceToSuffix := map[string]string{
					"北京":  "beijing",
					"福建":  "fujian",
					"海南":  "hainan",
					"黑龙江": "heilongjiang",
					"江苏":  "jiangsu",
					"吉林":  "jilin",
					"辽宁":  "liaoning",
					"上海":  "shanghai",
					"四川":  "sichuan",
					"浙江":  "zhejiang",
				}

				// 如果省份在映射中，则插入到对应的子表
				if suffix, exists := provinceToSuffix[province]; exists {
					subTableName := "tencent_k4_" + suffix

					// 获取子表字段并过滤数据
					subTableColumns, err := getTableColumns(subTableName)
					if err != nil {
						txSyncLogger.Error(fmt.Sprintf("获取表 %s 字段失败: %v", subTableName, err))
						fmt.Printf("获取表 %s 字段失败: %v\n", subTableName, err)
					} else {
						insertData["province"] = "k4_" + suffix
						subTableFilteredData := filterDataByColumns(insertData, subTableColumns)
						err = insertIntoTable(subTableName, subTableFilteredData)
						if err != nil {
							txSyncLogger.Error(fmt.Sprintf("插入 %s 表失败: %v", subTableName, err))
							fmt.Printf("插入 %s 表失败: %v\n", subTableName, err)
						}
					}
				}
			}
		}
	}

}

// insertIntoTable 插入数据到指定表
func insertIntoTable(tableName string, data map[string]interface{}) error {
	return common.DBDk.Table(tableName).Create(data).Error
}

// TxStructToMap 将结构体字段添加到 map 中（除了 id 字段）
func TxStructToMap(info models.TencentAccountView, data map[string]interface{}) {
	// 注意：这里需要根据实际的 TencentAccountView 结构体字段进行调整
	data["media"] = info.Media
	data["platform"] = info.Platform
	data["background"] = info.Background
	data["background_id"] = info.BackgroundID
	data["examine_status"] = info.ExamineStatus
	data["appid"] = info.AppID
	data["account_name"] = info.AccountName
	data["license"] = info.License
	data["primary_industry"] = info.PrimaryIndustry
	data["second_industry"] = info.SecondIndustry
	data["kpi_industry"] = info.KPIIndustry
	data["category"] = info.Category
	data["is_category"] = info.IsCategory
	data["is_link_box"] = info.IsLinkBox
	data["province"] = info.Province
	data["belong_kk"] = info.BelongKk
	data["belong_kk_2023_h2"] = info.BelongKk2023H2
	data["belong_kk_2023_h1"] = info.BelongKk2023H1
	data["sale"] = info.Sale
	data["first_department"] = info.FirstDepartment
	data["second_department"] = info.SecondDepartment
	data["source_class"] = info.SourceClass
	data["channel"] = info.Channel
	data["company_jc"] = info.CompanyJC
	data["company"] = info.Company
	data["is_new"] = info.IsNew
	data["new_open_belong"] = info.NewOpenBelong
	data["operation_type"] = info.OperationType
	data["import_remark"] = info.ImportRemark
	data["import_user_id"] = info.ImportUserID
	data["type"] = info.Type
	data["story"] = info.Story
	data["is_s2"] = info.IsS2
	data["line_one_three"] = info.LineOneThree
	data["yx_sh_bj"] = info.YxShBj
	data["company_sku"] = info.CompanySKU
	data["circulation_record"] = info.CirculationRecord
	data["circulation_status"] = info.CirculationStatus
	data["s2_days"] = info.S2Days
	data["youke_type"] = info.YoukeType
	data["s2_waist_guest"] = info.S2WaistGuest
	data["s2_waist_guest_days"] = info.S2WaistGuestDays
	data["is_old"] = info.IsOld
	data["is_financial"] = info.IsFinancial
	data["is_second_son"] = info.IsSecondSon
	data["suffix"] = info.Suffix
	data["frame_lable_2025"] = info.FrameLable2025
}

// isK4Type 判断是否为 K4 类型（strpos($parentLists[$copy['parent']]['suffix'], 'k4') !== false && $parentLists[$copy['parent']]['suffix'] != "k4"）
func isK4Type(suffix string) bool {
	// 检查是否包含 "k4" 子字符串且不等于 "k4"
	return len(suffix) > 2 && suffix != "k4" && containsIgnoreCase(suffix, "k4")
}

// containsIgnoreCase 检查字符串是否包含子字符串（不区分大小写）
func containsIgnoreCase(s, substr string) bool {
	return len(s) >= len(substr) &&
		(len(s) == len(substr) && s == substr ||
			len(s) > len(substr) && (s[:len(substr)] == substr || s[len(s)-len(substr):] == substr ||
				findSubstring(s, substr)))
}

// findSubstring 在字符串中查找子字符串
func findSubstring(s, substr string) bool {
	for i := 0; i <= len(s)-len(substr); i++ {
		if s[i:i+len(substr)] == substr {
			return true
		}
	}
	return false
}

// getValueOrDefault 获取值或默认值
func getValueOrDefault(value, defaultValue string) string {
	if value == "" {
		return defaultValue
	}
	return value
}

// getTableColumns 获取表的字段列表 - 使用 SHOW COLUMNS FROM SQL 语句
func getTableColumns(tableName string) ([]string, error) {
	rows, err := common.DBDk.Raw(fmt.Sprintf("SHOW COLUMNS FROM `%s`", tableName)).Rows()
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var columns []string
	for rows.Next() {
		var field, fieldType, null, key, defaultValue sql.NullString
		var extra sql.NullString

		// 根据 SHOW COLUMNS 的结果解析字段
		err := rows.Scan(&field, &fieldType, &null, &key, &defaultValue, &extra)
		if err != nil {
			return nil, err
		}

		if field.Valid {
			columns = append(columns, field.String)
		}
	}

	return columns, nil
}

// filterDataByColumns 根据允许的字段过滤数据
func filterDataByColumns(data map[string]interface{}, allowedColumns []string) map[string]interface{} {
	allowedMap := make(map[string]bool)
	for _, col := range allowedColumns {
		allowedMap[col] = true
	}

	filtered := make(map[string]interface{})
	for key, value := range data {
		if allowedMap[key] {
			filtered[key] = value
		}
	}
	return filtered
}
